﻿///*------------------------------------------------------------------------------
// * SourceCodeDownloader - Kerem Kusmezer (keremskusmezer@gmail.com)
// * 
// * Download all the .NET Reference Sources and PDBs to pre-populate your 
// * symbol server! No more waiting as each file downloads individually while
// * debugging.
// * ---------------------------------------------------------------------------*/
//#region Imported Libraries
//using System;
//using System.Collections.Generic;
//using System.Text;
//using System.IO;
//using System.Diagnostics;
//using SourceCodeThief.Classes.Eula;
//#endregion
//namespace SourceCodeThief.Classes
//{
//    public class PdbFileExtractor
//    {

//        #region Public Events

//        public delegate void EulaHandler(Object sender, EulaRequestEvent e);

//        public delegate void SourceCodeHandler(Object sender, SourceFileLoadEventArg e);

//        /// <summary>
//        /// Occurs When A File Is Downloaded
//        /// </summary>
//        public event SourceCodeHandler SourceFileDownloaded;

//        /// <summary>
//        /// Occurs During First Time Code Download Requested, 
//        /// If Eula Not Accepted The Engine Stops Downloading The Source Code
//        /// </summary>
//        public event EulaHandler EulaAcceptRequested;

//        protected virtual void OnEulaAcceptRequested(EulaRequestEvent e)
//        {
//            if (EulaAcceptRequested != null)
//            {
//                EulaAcceptRequested(this, e);
//            }
//        }

//        protected virtual void OnSourceFileDownloaded(SourceFileLoadEventArg e)
//        {
//            if (SourceFileDownloaded != null)
//            {
//                SourceFileDownloaded(this, e);
//            }
//        }



//        #endregion

//        #region Private Variables

//        public bool ShowDialog
//        {
//            get
//            {
//                return m_showDialog;
//            }
//            set
//            {
//                m_showDialog = value;
//            }
//        }
//        // The indexes into the srcsrv file info string where the pieces are 
//        // located.
//        private const int BuildIndex = 0;
//        private const int SrcSrvIndex = 1;
//        private const int SymbolIndex = 2;
//        private const int VersionIndex = 3;
//        private string m_pdbFileName;
//        private System.IO.MemoryStream m_pdbStream;
//        private bool m_showDialog;
//        private PdbParser m_internalPdbParser;
//        #endregion
               
//        #region Constructors

//        /// <summary>
//        /// The Generated Pdb Parser Around The Provided Pdb Stream
//        /// </summary>
//        public PdbParser InternalPdbParser
//        {
//            get { return m_internalPdbParser; }
//            private set { m_internalPdbParser = value; }
//        }

//        private void CreatePdbParser()
//        {
//            if (m_pdbStream != null)
//            {
//                m_internalPdbParser = 
//                    new PdbParser(m_pdbStream);
//            }
//            else
//            {
//                m_internalPdbParser = 
//                    new PdbParser(new System.IO.MemoryStream(System.IO.File.ReadAllBytes(m_pdbFileName)));
//            }
//        }

//        public PdbFileExtractor(string pdbFileName, System.IO.MemoryStream pdbStream)
//        {
//            m_pdbFileName = pdbFileName;
//            if (m_pdbStream == null)
//                throw new System.IO.FileNotFoundException("Following File Not Found", pdbFileName);
//            m_pdbStream = pdbStream;
//            CreatePdbParser();
//        }

//        public PdbFileExtractor(string pdbFileName)
//        {
//            if (System.IO.File.Exists(pdbFileName))
//            {
//                m_pdbFileName = pdbFileName;
//            }
//            else
//            {
//                throw new System.IO.FileNotFoundException("Following File Not Found", pdbFileName);
//            }
//            CreatePdbParser();
//        }

//        #endregion

//        #region Public Instance Methods

//        public List<SrcSrvDownloadAbleFile> RetrieveNormal(string targetPath)
//        {
//            String locatedFileIndex = LocateFileIndex();
//            return null;
//        }

//        public List<SrcSrvDownloadAbleFile> RetrieveFileRelationsExtended(string targetPath)
//        {
//            targetPath = Utility.CleanupPath(targetPath);
//            String locatedSrcSrvBody = LocateFileIndex();
//            SrcSrvFile tempSrcSrvFile = new SrcSrvFile(locatedSrcSrvBody, targetPath);
//            tempSrcSrvFile.ParseBody();
//            return tempSrcSrvFile.FilesToBeDownloaded;
//        }

//        public bool DownloadWholeFiles(string targetPath)
//        {
//            List<SrcSrvDownloadAbleFile> pdbResults = 
//                RetrieveFileRelationsExtended(targetPath);

//            List<SrcSrvDownloadAbleFile>.Enumerator tempEnum =
//                pdbResults.GetEnumerator();

//            int i = 1;
            
//            while (tempEnum.MoveNext())
//            {
                
//                PDBWebClient tempClient = Utility.GetWebClientWithCookie();
                
                

//                string directoryName = String.Empty;
//                try
//                {
//                    directoryName =
//                        System.IO.Path.GetDirectoryName(tempEnum.Current.LocalFileTarget);

//                    if (!System.IO.Directory.Exists(directoryName))
//                    {
//                        Directory.CreateDirectory(directoryName);
//                    }

//                    byte[] downloadedData =
//                           tempClient.DownloadData(tempEnum.Current.UrlToBeRequested);

//                    EulaRequestEvent eulaEventArg = null;

//                    if (tempClient.IsEulaResponse)
//                    {

//                        eulaEventArg =
//                            new EulaRequestEvent(new EulaContents(tempClient.EulaBody));

//                        OnEulaAcceptRequested(eulaEventArg);

//                        if (!eulaEventArg.EulaAccepted)
//                        {
//                            throw new EulaNotAcceptedException();
//                        }
//                        else
//                        {
//                            downloadedData =
//                                tempClient.DownloadData(tempEnum.Current.UrlToBeRequested + "?" + eulaEventArg.EulaContent.AcceptCmdKey);
//                        }

//                    }

//                    System.IO.File.WriteAllBytes(tempEnum.Current.LocalFileTarget,
//                                                 downloadedData);

//                    OnSourceFileDownloaded(new SourceFileLoadEventArg(tempEnum.Current.LocalFileTarget, tempEnum.Current.UrlToBeRequested, i.ToString() + "/" + pdbResults.Count));
//                }
//                catch (Exception ex)
//                {
//                    if (ex is EulaNotAcceptedException)
//                        throw;
//                    OnSourceFileDownloaded(new SourceFileLoadEventArg(tempEnum.Current.LocalFileTarget, tempEnum.Current.LocalFileTarget, i.ToString() + "/" + pdbResults.Count,ex));
//                }
//                i++;
//            }           
//            return true;
//        }

//        public Dictionary<String, String> RetrieveFileRelations(string targetPath)
//        {
//            targetPath = Utility.CleanupPath(targetPath);
//            Dictionary<String, String> fileRelations = new Dictionary<string, string>();
//            String locatedFileIndex = LocateFileIndex();
//            string[] sourceFiles =
//                locatedFileIndex.Split(new string[] { "SRCSRV: source files ---------------------------------------" }, StringSplitOptions.None);
//            if (sourceFiles.Length == 2)
//            {
//                System.IO.StringReader tester = new System.IO.StringReader(sourceFiles[1].Substring(0,sourceFiles[1].IndexOf("SRCSRV: end ------------------------------------------------")).Trim());
//                string pdbBodyToParse = null;
//                while ((pdbBodyToParse = tester.ReadLine()) != null)
//                {
//                    // Skip all empty lines.
//                    if (true == String.IsNullOrEmpty(pdbBodyToParse))
//                    {
//                        continue;
//                    }

//                    String[] processed = BuildKeyValuePairFromString(targetPath,
//                                                                       pdbBodyToParse);
                    
//                    if (null == processed)
//                    {
//                        Debug.WriteLine(pdbBodyToParse);
//                    }
//                    else
//                    {
//                        fileRelations.Add(processed[0], processed[1]);
//                    }                   
//                }
//            }
//            return fileRelations;
//        }

//        private String[] BuildKeyValuePairFromString(String targetPath, String srcsrvFile)
//        {
//            // Split the string on the asterisks.
//            String[] rawData = srcsrvFile.Split(new Char[] { '*' });
//            //Debug.Assert ( null != rawData , "null != rawData" );
//            //Debug.Assert ( rawData.Length == 4 , "rawData.Length == 4" );
//            try
//            {
//                if (rawData.Length != 4)
//                {
//                    return (null);
//                }
//                // Yes, recombine the symbol and version so we have that for the 
//                // value.
//                String downloadValue = rawData[SymbolIndex] + "*" +
//                                                           rawData[VersionIndex];
//                // Build up the output directory.
//                String targetKey = Utility.CleanupPath(targetPath);
//                targetKey += Utility.CleanupPath(rawData[SrcSrvIndex]);
//                targetKey += Utility.CleanupPath(rawData[SymbolIndex].
//                                                           Replace('/', '\\'));
//                targetKey += Utility.CleanupPath(rawData[VersionIndex]);
//                targetKey += Path.GetFileName(rawData[BuildIndex]);
//                return (new String[] { targetKey, downloadValue });
//            }
//            catch (Exception ex)
//            {
//                System.Diagnostics.Debug.WriteLine(ex.Message);
//                return (null);
//            }
//        }

//        public String LocateFileIndex()
//        {
//            MemoryStream srvsrcLocation = 
//                this.InternalPdbParser.GetStreamBeginsWithBytesArrayASCII(Constants.SRCSRVLocator);
//            return System.Text.Encoding.ASCII.GetString(srvsrcLocation.ToArray());
//        }

//        public bool UpdateFilePaths()
//        {
//            byte[] wholeLines =
//                System.IO.File.ReadAllBytes(m_pdbFileName);
//            wholeLines =
//                Utility.ReplaceInByteArray(wholeLines, Utility.ToByteArray("663a5c"), Utility.ToByteArray("633a5c"));
//            System.IO.File.WriteAllBytes(m_pdbFileName, wholeLines);
//            return true;
//        }

//        /*

//        public bool DownloadWholeFiles(string targetPath)
//        {
            
//            Dictionary<String, String> pdbResults = 
//                this.RetrieveFileRelations(targetPath);

//            Dictionary<String, String>.Enumerator tempEnum =
//              pdbResults.GetEnumerator();

//            //string rootHeader =               
//            //"depot/DevDiv/releases/whidbey/REDBITS/ndp/clr/src/BCL/System/EventArgs.cs/1/EventArgs.cs";

//            int i = 1;
//            while (tempEnum.MoveNext())
//            {
//                string restOfPath = String.Empty;
//                try
//                {
//                    PDBWebClient tempClient = Utility.GetWebClientWithCookie();

//                    string directoryName = String.Empty;
//                    try
//                    {
//                        directoryName = System.IO.Path.GetDirectoryName(tempEnum.Current.Key);
//                    }
//                    catch (ArgumentException ex)
//                    {
//                        System.Diagnostics.Debug.WriteLine(ex);
//                        directoryName = tempEnum.Current.Key;
//                        char[] invalidChars = System.IO.Path.GetInvalidPathChars();
//                        for (int ix = 0; ix < invalidChars.Length; ix++)
//                        {
//                            directoryName = directoryName.Replace(invalidChars[ix].ToString(), String.Empty);
//                        }
//                        directoryName = System.IO.Path.GetDirectoryName(tempEnum.Current.Key);
//                    }

//                    System.IO.Directory.CreateDirectory(directoryName);

//                    string targetFileName =
//                        System.IO.Path.GetFileName(tempEnum.Current.Key);

//                    restOfPath = tempEnum.Current.Value;

//                    restOfPath = restOfPath.Replace("*", "/") + "/" + targetFileName;

//                    restOfPath = Constants.rootHeader + restOfPath;

//                    byte[] downloadedData = 
//                        tempClient.DownloadData(restOfPath);

//                    EulaRequestEvent eulaEventArg = null;

//                    if (tempClient.IsEulaResponse)
//                    {                        
                     
//                        eulaEventArg = 
//                            new EulaRequestEvent(new EulaContents(tempClient.EulaBody));

//                        OnEulaAcceptRequested(eulaEventArg);

//                        if (!eulaEventArg.EulaAccepted)
//                        {
//                            throw new EulaNotAcceptedException();
//                        }
//                        else
//                        {
//                            downloadedData =
//                                tempClient.DownloadData(restOfPath +"?" + eulaEventArg.EulaContent.AcceptCmdKey);
//                        }

//                    }

//                    System.IO.File.WriteAllBytes(targetFileName,
//                                                 downloadedData);

//                    OnSourceFileDownloaded(new SourceFileLoadEventArg(tempEnum.Current.Key, restOfPath, i.ToString() + "/" + pdbResults.Count));

//                }
//                catch (Exception ex)
//                {
                    
//                    if (ex is EulaNotAcceptedException)
//                        throw;

//                    OnSourceFileDownloaded(new SourceFileLoadEventArg(tempEnum.Current.Key, restOfPath, i.ToString() + "/" + pdbResults.Count, ex));

//                }
//                i++;
//            }
//            return true;
//        }
        

//        */

//        #endregion

//    }
//}